#include "characterclass.h"
#include "skill.h"
#include "classlevel.h"
#include "characterfeature.h"


#include <QTimer>
#include <QMetaProperty>
#include <QStringList>


CharacterClass::CharacterClass(QObject *parent) :
    DTwentyItem(parent)
{
    qRegisterMetaType<CharacterFeatures*>();
    qRegisterMetaType<ClassLevels*>();
    qRegisterMetaType<Skills*>();

    QTimer::singleShot(0, this, SLOT(onInitChildren()));

}

CharacterClass::CharacterClass(const CharacterClass& other) :
    DTwentyItem(other)
{
}

int CharacterClass::calcBaseBonus(int level, int category)
{
    switch (category)
    {
    case CharacterFeature::Excellent:
        return level;

    case CharacterFeature::Ordinary:
        return (level-1) - ((level-1)/4);

    case CharacterFeature::Poor:
        return (level-1)/2;

    default:
        break;
    }

    return -1;
}

int CharacterClass::calcSaveBonus(int level, int category)
{
    switch (category)
    {
    case CharacterFeature::Normal:
        return (level/3);

    case CharacterFeature::Good:
        return (level/2)+2;

    default:
        break;
    }

    return -1;
}

int CharacterClass::type() const
{
    return qMetaTypeId<CharacterClass*>();
}

int CharacterClass::hitDie() const
{
    return featureValue(CharacterFeatures::HitDie);
}

int CharacterClass::skillPoints() const
{
    return featureValue(CharacterFeatures::SkillPoints);
}

int CharacterClass::baseAttack() const
{
    return featureValue(CharacterFeatures::BaseAttack);
}

int CharacterClass::fortSave() const
{
    return featureValue(CharacterFeatures::FortSave);
}

int CharacterClass::refSave() const
{
    return featureValue(CharacterFeatures::RefSave);
}

int CharacterClass::willSave() const
{
    return featureValue(CharacterFeatures::WillSave);
}

QString CharacterClass::abbreviation() const
{
    QStringList parts = name().split(" ");
    QString abbr;
    if (parts.count() == 0)
    {
        abbr = "[?]";
    }
    else if (parts.count() == 1)
    {
        abbr = parts.first().left(3);
    }
    else
    {
        abbr = parts.value(0).left(1) + parts.value(1).left(2);
    }

    return abbr;
}


void CharacterClass::onInitChildren()
{

    QString featureName = tr("Features");
    QString levelName = tr("Levels");
    QString skillsName = tr("Class Skills");

    initChild<CharacterFeatures>(featureName);
    initChild<ClassLevels>(levelName);

    Skills* classSkills = initChild<Skills>(skillsName);
    Skills* campaignSkills = rootItem()->findChild<Skills*>(QString(), Qt::FindDirectChildrenOnly);

    if (!campaignSkills)
    {
        return;
    }

    classSkills->setValueSource(campaignSkills);
}

int CharacterClass::featureValue(int id) const
{
    CharacterFeatures* features = findChild<CharacterFeatures*>(QString(), Qt::FindDirectChildrenOnly);
    if (!features)
    {
        qDebug() << Q_FUNC_INFO << "Failed to find features object!";
        return -1;
    }

    foreach (CharacterFeature* feature, features->findChildren<CharacterFeature*>(QString(), Qt::FindDirectChildrenOnly))
    {
        if (feature->id() == id)
        {
            return feature->value();
        }
    }

    return -1;
}

bool CharacterClass::setFeatureValue(int id, QVariant value)
{
    CharacterFeatures* features = findChild<CharacterFeatures*>(QString(), Qt::FindDirectChildrenOnly);
    if (!features)
    {
        qDebug() << Q_FUNC_INFO << "Failed to find features object!";
        return false;
    }

    foreach (CharacterFeature* feature, features->findChildren<CharacterFeature*>(QString(), Qt::FindDirectChildrenOnly))
    {
        if (feature->id() == id)
        {
            feature->setValue(value.toInt());
            return true;
        }
    }

    return false;
}
